package yu

import (
	"sync"
	"time"
)

// IQueue 队列接口
type IQueue interface {
	Start()
	Stop()
	Submit(args any, sync bool)
}

// Queue 队列
type queue struct {
	count int
	que   chan any
	deal  func(any)
	wg    *sync.WaitGroup
	stch  chan struct{}
}

// NewQueue 新建队列
func NewQueue(size, count int, deal func(any)) IQueue {
	return &queue{
		count: count,
		que:   make(chan any, size),
		deal:  deal,
		wg:    new(sync.WaitGroup),
		stch:  make(chan struct{}),
	}
}

// Start 启动队列
func (q *queue) Start() {
	for i := 0; i < q.count; i++ {
		q.wg.Add(1)
		go func() {
			defer q.wg.Done()
			for item := range q.que {
				q.deal(item)
			}
		}()
	}
}

// Stop 停止队列
func (q *queue) Stop() {
	close(q.stch)
	time.Sleep(100 * time.Millisecond)
	close(q.que)
	q.wg.Wait()
}

// Submit 添加任务到队列
func (q *queue) Submit(args any, sync bool) {
	if sync {
		q.submit(args)
		return
	}
	go func(a any) { q.submit(args) }(args)
}

func (q *queue) isStop() bool {
	select {
	case <-q.stch:
		return true
	default:
		return false
	}
}

func (q *queue) submit(i any) {
	if q.isStop() {
		return
	}
	q.que <- i
}

// QueueManager 队列管理器
type QueueManager struct {
	ques []IQueue
}

// NewQueueManager 新建队列管理器
func NewQueueManager() *QueueManager {
	return &QueueManager{
		ques: make([]IQueue, 0),
	}
}

// AddQueue 管理器中添加队列
func (qm *QueueManager) AddQueue(q IQueue) {
	qm.ques = append(qm.ques, q)
}

// GetQueue 管理器中获取队列
func (qm *QueueManager) GetQueue(i int) IQueue {
	q := qm.ques[i]
	return q
}

// PushQueue 添加任务到管理器队列中
func (qm *QueueManager) PushQueue(i int, args interface{}) {
	qm.ques[i].Submit(args, true)
}

// StartQueue 管理器启动所有队列
func (qm *QueueManager) StartQueues() {
	for _, q := range qm.ques {
		q.Start()
	}
}
